/**
 * Copyright (c) Tapas Mobile.  All Rights Reserved.
 *
 * @author DaiHui 
 * @version 1.0
 */

package com.dotools.utils;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.dotools.compat.MissedAPI;
import com.dotools.debug.LOG;
import com.dotools.thread.ThreadPool;

public class Utilities {
    static Context sApplicationContext = null;
    static String sAppliationName = null;
    static String sMainProcessName = null;
    
    static Integer sVersionCode = null;
    static String sVersionName = null;
    public static void initEnvironment(Context ctx, String name, String mainProcessName) {
        sApplicationContext = ctx;
        sAppliationName = name;
        sMainProcessName = mainProcessName;
    }


    public static Context getApplicationContext() {
        if (sApplicationContext == null) {
            throw new java.lang.IllegalStateException("Common library is used before initialize!");
        }

        return sApplicationContext;
    }

    public static void destoyApplicationContext(){
        if(sApplicationContext != null){
            sApplicationContext = null;
        }
    }

    public static int getVersionCode(){
        if(sVersionCode != null){
            try {
                sVersionCode = sApplicationContext.getPackageManager().getPackageInfo(sApplicationContext.getPackageName(), 0).versionCode;
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return sVersionCode == null ? 0 : sVersionCode.intValue();
    }

    public static String getVersionName(){
        if(TextUtils.isEmpty(sVersionName)){
            try {
                sVersionName = sApplicationContext.getPackageManager().getPackageInfo(sApplicationContext.getPackageName(), 0).versionName;
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return sVersionName;
    }

    public static String getApplicationName() {
        return sAppliationName;
    }

    public static void runBackgroundInitializer() {
        ThreadPool.runOnPool(new Runnable() {
            @Override
            public void run() {
                // load physical memory data
                DevicesUtils.getPhysicalMemoryKBs();
            }
        });

        ThreadPool.runOnPool(new Runnable() {
            @Override
            public void run() {
                MissedAPI.init();
            }
        });
//
//        ThreadPool.runOnPool(new Runnable() {
//            @Override
//            public void run() {
//                ReflectWallpaperManager.init();
//            }
//        });
    }

    public static void setVmMemoryPolicy() {
        // // set minumum heap size to 12MB
        // VMRuntime.getRuntime().setMinimumHeapSize(12 * 1024 * 1024);
        // // set expected heap utilization to 85%, default is 50%; reduce GC frequency
        // VMRuntime.getRuntime().setTargetHeapUtilization(0.85f);

        try {
            ClassLoader cl = ClassLoader.getSystemClassLoader();
            Class<?> clsVMRuntime;

            clsVMRuntime = cl.loadClass("dalvik.system.VMRuntime");

            Method methodGetRuntime = clsVMRuntime.getMethod("getRuntime", new Class<?>[] {});
            Method methodSetMinimumHeapSize = clsVMRuntime.getMethod("setMinimumHeapSize", new Class<?>[] {
                long.class
            });
            Method methodSetTargetHeapUtilization = clsVMRuntime.getMethod("setTargetHeapUtilization", new Class<?>[] {
                float.class
            });

            final int minHeap = Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1 ? 8 : 12;
            Object objRuntime = methodGetRuntime.invoke(null, (Object[]) null);
            methodSetMinimumHeapSize.invoke(objRuntime, minHeap * 1024 * 1024);
            methodSetTargetHeapUtilization.invoke(objRuntime, 0.85f);

            LOG.logI("set vm parameters done");
        } catch (ClassNotFoundException e) {
        } catch (SecurityException e) {
        } catch (NoSuchMethodException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        }
    }

    public static boolean isSDCardMounted() {
        return Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    }

    public static void silentlyClose(Closeable c) {
        if (c != null) {
            try {
                c.close();
            } catch (Throwable e) {
            }
        }
    }

    public static void silentlyClose(Cursor c) {
        if (c != null) {
            try {
                c.close();
            } catch (Throwable e) {
            }
        }
    }

    public static void silentlyClose(SQLiteDatabase c) {
        if (c != null) {
            try {
                c.close();
            } catch (Throwable e) {
            }
        }
    }

    public static String getCurrentLanguage() {
        return Locale.getDefault().getLanguage();
    }

    private static Boolean sIsLargeScreen = null;

    public static boolean isLargeScreen() {
        if (sIsLargeScreen == null) {
            Resources resources = getApplicationContext().getResources();
            final int screenSize = resources.getConfiguration().screenLayout
                    & Configuration.SCREENLAYOUT_SIZE_MASK;
            sIsLargeScreen = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE
                    || screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;
        }
        return sIsLargeScreen;
    }

    public static void printArray(String name, int[] array) {
        StringBuilder sb = new StringBuilder();
        sb.append(name == null ? "" : name).append(":[");
        for (int i = 0; i < array.length - 1; i++) {
            sb.append(array[i]).append(",");
        }
        sb.append(array[array.length - 1]).append("]");
        LOG.logI(sb.toString());
    }

    public static void printArray(String name, float[] array) {
        StringBuilder sb = new StringBuilder();
        sb.append(name == null ? "" : name).append(":[");
        for (int i = 0; i < array.length - 1; i++) {
            sb.append(array[i]).append(",");
        }
        sb.append(array[array.length - 1]).append("]");
        LOG.logI(sb.toString());
    }

    public static void printArray(String name, Object[] array) {
        StringBuilder sb = new StringBuilder();
        sb.append(name == null ? "" : name).append(":[");
        for (int i = 0; i < array.length - 1; i++) {
            sb.append(array[i]).append(",");
        }
        sb.append(array[array.length - 1]).append("]");
        LOG.logI(sb.toString());
    }

    public static boolean supportVelocityWithParam() {
        return Build.VERSION.SDK_INT >= 8;
    }
}
